import requests
from datetime import datetime
from SqlalchemyConfig import SessionLocal
from models.Emergency import EmergencyVo
from RedisClient import RedisClient
from ConfigReader import get_auth_api_base_url, get_auth_api_third_url
import logging
import configparser
import os

logger = logging.getLogger(__name__)
redis_client = RedisClient()


def read_codes_from_config(config_file='Config.ini'):
    """读取配置文件中的地区编码"""
    config = configparser.ConfigParser()
    if not os.path.exists(config_file):
        logger.error(f"❌ 配置文件 {config_file} 不存在")
        return []

    config.read(config_file)
    areas = config['Areas']
    return list(areas.values())


def send_broadcast_alert(code, description, headers, base_url):
    """
    向广播接口发送预警消息

    :param code: 地区编码
    :param description: 预警描述文本
    :param headers: 请求头（如 Authorization）
    :param base_url: 接口基础 URL
    :return: 是否成功
    """
    form_data = {
        "level": 1,  # 固定值
        "volume": 30,  # 固定值
        "targets": [code],  # JSON 数组自动由 requests 处理
        "emergency": 4,  # 固定值
        "text": description  # 描述内容
    }

    broadcast_url = f"{base_url.rstrip('/')}/api/v1/broadcast/filetext"

    try:
        response = requests.post(broadcast_url, data=form_data, headers=headers, timeout=10)

        if response.status_code == 200:
            res_json = response.json()
            if res_json.get("code") == "00000":
                broadcast_id = res_json["content"].get("broadcastId")
                logger.info(f"📢 广播已成功发送，Broadcast ID: {broadcast_id}")
                return True
            else:
                logger.warning(f"⚠️ 广播接口返回非成功状态码：{res_json.get('message')}")
                return False
        else:
            logger.warning(f"⚠️ 请求失败，状态码：{response.status_code}")
            return False

    except Exception as e:
        logger.error(f"❌ 发送广播消息失败：{str(e)}", exc_info=True)
        return False

def send_third_party_alert(code, description, third_url):
    """
    向第三方接口发送预警消息

    :param third_url: 三方接口
    :param code: 地区编码
    :param description: 预警描述文本
    :return: 是否成功
    """
    broadcast_url = f"{third_url.rstrip('/')}/index.php?s=httpapi&id=8&appid=3&appsecret=ZONGHE402C077A8163D"
    form_data = {
        "gbbm": code,
        "content": description
    }

    try:
        response = requests.post(broadcast_url, data=form_data, timeout=10)

        if response.status_code == 200:
            logger.info(f"🔌 第三方接口调用成功，响应内容：{response.text[:200]}")
            return True
        else:
            logger.warning(f"⚠️ 第三方接口请求失败，状态码：{response.status_code}")
            return False

    except Exception as e:
        logger.error(f"❌ 调用第三方接口失败：{str(e)}", exc_info=True)
        return False


def fetch_and_store_emergency_data():
    """
    获取多个地区的天气预警信息并写入数据库。
    如果发现新预警，则推送广播消息。
    """
    codes = read_codes_from_config()
    if not codes:
        logger.warning("⚠️ 没有读取到任何地区编码，跳过本次抓取。")
        return False

    base_url = get_auth_api_base_url()
    third_url = get_auth_api_third_url()

    if not base_url:
        logger.critical("🛑 获取 base_url 失败，无法发送广播。")
        return False

    if not third_url:
        logger.critical("🛑 获取 third_url 失败，无法推送消息。")
        return False

    auth_token = redis_client.get_token()
    if not auth_token:
        logger.critical("🛑 Redis 中无 Token，无法发送广播。")
        return False

    headers = {
        "Authorization": auth_token
    }

    for code in codes:
        url = f"https://weather.cma.cn/api/map/alarm?adcode={code}"
        logger.info(f"📡 正在获取灾害预警数据：{url}")
        db = SessionLocal()
        flag = 0

        try:
            response = requests.get(url, timeout=10)
            if response.status_code != 200:
                logger.warning(f"⚠️ 请求失败 [{code}]，状态码：{response.status_code}")
                continue

            data = response.json().get('data', [])
            if not data:
                logger.info(f"ℹ️ [{code}] 当前无预警数据。")
                continue

            effective = datetime.strptime(data[0]['effective'], "%Y/%m/%d %H:%M")

            for item in data:
                existing = db.query(EmergencyVo).filter(EmergencyVo.emergency_id == item['id']).first()

                if existing:
                    continue

                # 插入新记录
                emergency = EmergencyVo(
                    emergency_id=item['id'],
                    code=code,
                    headline=item['headline'],
                    effective=datetime.strptime(item['effective'], "%Y/%m/%d %H:%M"),
                    description=item['description'],
                    longitude=item['longitude'],
                    latitude=item['latitude'],
                    type=item['type'],
                    title=item['title'],
                    creat_time=datetime.now(),
                    update_time=datetime.now()
                )
                db.add(emergency)
                flag += 1

                # 推送两个接口
                success1 = send_broadcast_alert(code, item['description'], headers, base_url)
                success2 = send_third_party_alert(code, item['description'], third_url)

                if success1:
                    logger.info(f"✅ [{code}] 广播预警推送成功")
                else:
                    logger.warning(f"❌ [{code}] 广播预警推送失败")

                if success2:
                    logger.info(f"✅ [{code}] 第三方接口预警推送成功")
                else:
                    logger.warning(f"❌ [{code}] 第三方接口预警推送失败")

            db.commit()
            logger.info(f"✅ [{code}] 最新预警时间：{effective}")
            logger.info(f"✅ [{code}] 已成功写入 {flag} 条预警数据！")

        except Exception as e:
            db.rollback()
            logger.error(f"❌ [{code}] 数据抓取或写入出错：{str(e)}", exc_info=True)
        finally:
            db.close()

    return True